home *** CD-ROM | disk | FTP | other *** search
- // Adapted from NVidia's HardwareShadowMap example, from NVSDK 7.0
- //-----------------------------------------------------------------------------
-
- texture ShadowMap;
- texture ShadowColorBuffer;
- texture ModelTexture;
-
- //-----------------------------------------------------------------------------
-
- float4x4 WorldViewProj;
- float4x4 WorldIT;
- float4x4 TexTransform;
- float3 sunlight_direction;
- float4 sunlight_color;
- float4x4 light_MVP;
- float zbias;
- float3 moonlight_direction;
- float4 moonlight_color;
- float4 material_diffuse_color;
- float4 material_ambient_color;
- float4 global_ambient_color;
- float one_minus_shadowalpha;
- float shadowalpha;
- float fogEnd;
- float fogEndMinusStartInv; // Calculated by C++: 1 / (FogEnd - FogStart)
-
- //-----------------------------------------------------------------------------
-
- struct VS_INPUT_TER {
- float3 Position : POSITION;
- float3 Normal : NORMAL;
- float4 Color0 : COLOR0;
- float2 TexCoord0 : TEXCOORD0;
- };
-
- struct VS_OUTPUT_TER {
- float4 Position : POSITION;
- float4 TexCoord0 : TEXCOORD0;
- float4 TexCoord1 : TEXCOORD1;
- float2 TexCoord2 : TEXCOORD2;
- float4 Color0 : COLOR0;
- float Fog : FOG;
- };
-
- struct VS_INPUT_OBJ {
- float4 Position : POSITION;
- float3 Normal : NORMAL;
- float4 TexCoord0 : TEXCOORD0;
- };
-
- struct VS_OUTPUT_OBJ {
- float4 Position : POSITION;
- float4 TexCoord0 : TEXCOORD0;
- float4 TexCoord1 : TEXCOORD1;
- float2 TexCoord2 : TEXCOORD2;
- float2 TexCoord3 : TEXCOORD3;
- float4 Color0 : COLOR0;
- float Fog : FOG;
- };
-
- //-----------------------------------------------------------------------------
-
- sampler ShadowMapSampler = sampler_state
- {
- Texture = <ShadowMap>;
- MinFilter = Linear;
- MagFilter = Linear;
- MipFilter = None;
- AddressU = Clamp;
- AddressV = Clamp;
- AddressW = Clamp;
- };
-
- sampler ShadowColorBufferSampler = sampler_state
- {
- Texture = <ShadowColorBuffer>;
- MinFilter = Linear;
- MagFilter = Linear;
- MipFilter = None;
- AddressU = Clamp;
- AddressV = Clamp;
- AddressW = Clamp;
- };
-
- sampler ModelTextureSampler = sampler_state
- {
- Texture = <ModelTexture>;
- MinFilter = Linear;
- MagFilter = Linear;
- MipFilter = Linear;
- };
-
- //-----------------------------------------------------------------------------
-
- // vertex shader to combine shadow map texture with model drawing to create shadows
- // this shader is used when drawing objects.
- VS_OUTPUT_OBJ CombineShadowObjectsVS(VS_INPUT_OBJ IN)
- {
- VS_OUTPUT_OBJ OUT;
-
- OUT.Position = mul(IN.Position, WorldViewProj);
-
- OUT.Fog = clamp(((fogEnd - OUT.Position.w) * fogEndMinusStartInv), 0.0f, 1.0f);
-
- OUT.TexCoord2 = IN.TexCoord0;
-
- // TexTransform = light MVP matrix * texture adjustment matrix
- // transform model-space vertex position to light-space:
- OUT.TexCoord0 = mul(IN.Position, TexTransform);
- OUT.TexCoord0.z += zbias; // add z-bias to prevent inappropriate self-shadowing
- OUT.TexCoord1 = mul(IN.Position, TexTransform);
-
- float sun_intensity = dot(IN.Normal, sunlight_direction);
-
- // If the polygon is not facing the light, do *NOT* shadow it.
- OUT.TexCoord3 = sun_intensity;
-
- float4 moonDiffuseColor = max(0, dot(IN.Normal, moonlight_direction)); // face doesn't receive moonlight if it's not facing the moon
- moonDiffuseColor *= moonlight_color * material_diffuse_color;
-
- float4 DiffuseColor = max(0, sun_intensity); // face doesn't receive sunlight if it's not facing the sun
- DiffuseColor *= sunlight_color * material_diffuse_color; //!NOTE what about alpha?
-
- DiffuseColor += moonDiffuseColor; // add moonlight color
- OUT.Color0 = DiffuseColor + global_ambient_color * material_ambient_color;
- //!NOTE: no incoming vertex color
-
- return OUT;
- }
-
- //-----------------------------------------------------------------------------
-
- // pixel shader to combine shadow map texture with model drawing to create shadows
- // used when drawing objects
- float4 CombineShadowObjectsPS(VS_OUTPUT_OBJ IN) : COLOR
- {
- float myColorBuffer = tex2Dproj(ShadowColorBufferSampler, IN.TexCoord1 ).r;
-
- // Note that shadow should range from one_minus_shadowalpha (full shadow) to 1 (no shadow).
- float4 shadow;
- if (myColorBuffer == 1 )
- {
- // If myColorBuffer is 1, then that part of the shadow map hasn't been written to, so there is no shadow.
- // Note: this is a hack to get around the fact that NVidia's shadow buffer doesn't clamp correctly.
- shadow = float4(1,1,1,1);
- }
- else if (IN.TexCoord3.x <= 0)
- {
- // If IN.TexCoord3.x < 0, then the triangle is facing away from the light
- // Tried a bunch of different things here, including setting the pixel to be shadowed, and fading
- // in a shadow depending on the value in IN.TexCoord3.x. None of these are perfect, since
- // the shadow doesn't quite match up with the regular object diffuse & ambient shading.
- // If you set it to no shadow, then it looks weird when a figure is completely in a building's shadow.
- // Half of the figure will be shadowed, and half won't. Other than that, it looks good & it's fast.
- shadow = float4(1,1,1,1); // no shadow
- }
- else
- {
- // Get the shadow value from the shadow map buffer and convert it to the correct range.
- shadow = tex2Dproj(ShadowMapSampler, IN.TexCoord0 ) * shadowalpha + one_minus_shadowalpha;
- }
- shadow.a = 1; // shadow alpha = 1.0 (ie shadow doesn't reduce alpha)
-
- float4 color = tex2D(ModelTextureSampler, IN.TexCoord2) * IN.Color0 * shadow;
- return color;
- }
-
-
- //-----------------------------------------------------------------------------
-
- // vertex shader to combine shadow map texture with model drawing to create shadows
- // this shader is used when drawing the terrain.
- VS_OUTPUT_TER CombineShadowTerrainVS(VS_INPUT_TER IN)
- {
- VS_OUTPUT_TER OUT;
-
- // transform model-space vertex position to screen space:
- OUT.Position = mul(float4(IN.Position, 1), WorldViewProj);
-
- OUT.Fog = clamp(((fogEnd - OUT.Position.w) * fogEndMinusStartInv), 0.0f, 1.0f);
-
- OUT.TexCoord2 = IN.TexCoord0;
-
- // transform model-space vertex position to light-space:
- OUT.TexCoord0 = mul(float4(IN.Normal, 1), TexTransform); // Normal is actually world position untransformed by C++
- OUT.TexCoord1 = mul(float4(IN.Normal, 1), TexTransform);
-
- OUT.Color0 = IN.Color0;
-
- return OUT;
- }
-
- //-----------------------------------------------------------------------------
-
- // pixel shader to combine shadow map texture with model drawing to create shadows
- // used when drawing terrain
- float4 CombineShadowTerrainPS(VS_OUTPUT_TER IN) : COLOR
- {
- // If myColorBuffer is 1, then that part of the shadow map hasn't been written to, so there is no shadow.
- // Note: this is a hack to get around the fact that NVidia's shadow buffer doesn't clamp correctly.
- float myColorBuffer = tex2Dproj(ShadowColorBufferSampler, IN.TexCoord1 ).r;
-
- float4 shadow;
-
- // Note that shadow should range from one_minus_shadowalpha (full shadow) to 1 (no shadow).
-
- shadow = (myColorBuffer == 1 ) ?
- float4(1,1,1,1) :
- tex2Dproj(ShadowMapSampler, IN.TexCoord0 ) * shadowalpha + one_minus_shadowalpha;
- shadow.a = 1; // shadow alpha = 1.0 (ie shadow doesn't reduce alpha)
-
- float4 color = tex2D(ModelTextureSampler, IN.TexCoord2) * IN.Color0 * shadow;
- return color;
- }
-
- //-----------------------------------------------------------------------------
-
- technique CombineShadowMapWithTerrain
- {
- pass P0
- {
- VertexShader = compile vs_1_1 CombineShadowTerrainVS();
- PixelShader = compile ps_2_0 CombineShadowTerrainPS();
-
- Texture[0] = <ShadowMap>;
- Texture[1] = <ShadowColorBuffer>;
- Texture[2] = <ModelTexture>;
- TexCoordIndex[0] = 0;
- TexCoordIndex[1] = 1;
- TexCoordIndex[2] = 2;
- TextureTransformFlags[0] = Projected | Count4; // maybe not necessary for PS 2.0?
- TextureTransformFlags[1] = Projected | Count4;
- TextureTransformFlags[2] = Disable;
-
- // ZEnable = True;
- // AlphaBlendEnable = False;
- // Lighting = False;
- // CullMode = None;
-
- // TexCoordIndex[0] = 0;
- // TexCoordIndex[1] = 1;
- // TextureTransformFlags[0] = Projected; //!NOTE always need these? See NVidia guy's note
- // TextureTransformFlags[1] = Projected;
- }
- }
-
- //-----------------------------------------------------------------------------
-
- technique CombineShadowMapWithObjects
- {
- pass P0
- {
- VertexShader = compile vs_1_1 CombineShadowObjectsVS();
- PixelShader = compile ps_2_0 CombineShadowObjectsPS();
-
- Texture[0] = <ShadowMap>;
- Texture[1] = <ShadowColorBuffer>;
- Texture[2] = <ModelTexture>;
- TexCoordIndex[0] = 0;
- TexCoordIndex[1] = 1;
- TexCoordIndex[2] = 2;
- TextureTransformFlags[0] = Projected | Count4;
- TextureTransformFlags[1] = Projected | Count4;
- TextureTransformFlags[2] = Disable;
-
- // ZEnable = True;
- // AlphaBlendEnable = False;
- // Lighting = False;
- // CullMode = None;
-
- // TexCoordIndex[0] = 0;
- // TexCoordIndex[1] = 1;
- // TextureTransformFlags[0] = Projected; //!NOTE always need these? See NVidia guy's note
- // TextureTransformFlags[1] = Projected;
- }
- }
-